package us.mooresr.geartrack.client.core.presenter;

import java.util.List;

import com.gwtplatform.dispatch.shared.DispatchAsync;
import com.gwtplatform.mvp.client.HasUiHandlers;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.View;
import com.gwtplatform.mvp.client.annotations.ProxyCodeSplit;
import com.gwtplatform.mvp.client.annotations.NameToken;
import us.mooresr.geartrack.client.place.NameTokens;
import com.gwtplatform.mvp.client.proxy.ProxyPlace;
import com.google.inject.Inject;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.gwtplatform.mvp.client.proxy.RevealContentEvent;
import us.mooresr.geartrack.client.core.presenter.MainPresenter;
import us.mooresr.geartrack.client.events.LocationChangedEvent;
import us.mooresr.geartrack.client.events.LocationCreatedEvent;
import us.mooresr.geartrack.client.events.LocationDeletedEvent;
import us.mooresr.geartrack.client.events.PersonCreatedEvent;
import us.mooresr.geartrack.client.events.PersonDeletedEvent;
import us.mooresr.geartrack.shared.action.DeleteLocationAction;
import us.mooresr.geartrack.shared.action.DeleteLocationResult;
import us.mooresr.geartrack.shared.action.DeletePersonAction;
import us.mooresr.geartrack.shared.action.DeletePersonResult;
import us.mooresr.geartrack.shared.action.GetAllLocationsAction;
import us.mooresr.geartrack.shared.action.GetAllLocationsResult;
import us.mooresr.geartrack.shared.action.GetAllPeopleAction;
import us.mooresr.geartrack.shared.action.GetAllPeopleResult;
import us.mooresr.geartrack.shared.action.PutLocationAction;
import us.mooresr.geartrack.shared.action.PutLocationResult;
import us.mooresr.geartrack.shared.model.Location;

public class LocationPresenter extends
		Presenter<LocationPresenter.MyView, LocationPresenter.MyProxy>
		implements LocationUiHandlers {
	
	private final DispatchAsync dispatcher;

	public interface MyView extends View, HasUiHandlers<LocationUiHandlers> {
		public void setLocationList(List<Location> list);
		public void addLocationToList(Location location);
		public void removeLocationFromList(Location location);
		public void updateListEntry(Location location);
	}

	@ProxyCodeSplit
	@NameToken(NameTokens.locations)
	public interface MyProxy extends ProxyPlace<LocationPresenter> {
	}

	@Inject
	public LocationPresenter(final EventBus eventBus, final MyView view,
			final MyProxy proxy, DispatchAsync dispatcher) {
		super(eventBus, view, proxy);
		getView().setUiHandlers(this);
		
		this.dispatcher = dispatcher;
	}

	@Override
	protected void revealInParent() {
		RevealContentEvent.fire(this, MainPresenter.TYPE_SetMainContent, this);
	}

	@Override
	protected void onBind() {
		super.onBind();
		
		addRegisteredHandler(LocationCreatedEvent.getType(), new LocationCreatedEvent.LocationCreatedHandler() {

			@Override
			public void onLocationCreated(LocationCreatedEvent event) {
				getView().addLocationToList(event.getLocation());
				
			}
			
		});
		
		addRegisteredHandler(LocationDeletedEvent.getType(), new LocationDeletedEvent.LocationDeletedHandler() {
			
			@Override
			public void onLocationDeleted(LocationDeletedEvent event) {
				getView().removeLocationFromList(event.getLocation());
				
			}
		});
		
		addRegisteredHandler(LocationChangedEvent.getType(), new LocationChangedEvent.LocationChangedHandler() {
			
			@Override
			public void onLocationChanged(LocationChangedEvent event) {
				getView().updateListEntry(event.getLocation());
				
			}
		});
	}
	
	
	@Override
	public void onReveal() {
		super.onReveal();
		
		// Launch a request to get the location list data
		GetAllLocationsAction action = new GetAllLocationsAction();
		
		dispatcher.execute(action,  new AsyncCallback<GetAllLocationsResult>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(GetAllLocationsResult result) {
				getView().setLocationList(result.getLocations());
				
			}
			
		});	
	}

	@Override
	public void addLocation(Location location) {
		PutLocationAction action = new PutLocationAction(location);
		
		dispatcher.execute(action, new AsyncCallback<PutLocationResult>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(PutLocationResult result) {
				LocationCreatedEvent.fire(getEventBus(), result.getLocationOut());
				
			}
			
		});
		
	}

	@Override
	public void deleteLocation(Location location) {
		DeleteLocationAction action = new DeleteLocationAction(location);
		
		dispatcher.execute(action, new AsyncCallback<DeleteLocationResult>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(DeleteLocationResult result) {
				LocationDeletedEvent.fire(getEventBus(), result.getLocationOut());
			}
			
		});
		
	}

	@Override
	public void updateLocation(Location location) {
		PutLocationAction action = new PutLocationAction(location);
		
		dispatcher.execute(action, new AsyncCallback<PutLocationResult>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(PutLocationResult result) {
				LocationChangedEvent.fire(getEventBus(), result.getLocationOut());
				
			}
			
		});
		
	}
}
